﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Globalization;
using System.Threading;
using Tilver.ExceptionHandling;

namespace Tilver.Common
{
    /// <summary>
    /// 日志输出帮助类
    /// </summary>
    internal class LogEntry
    {
        public Type MessageType;
        public object Message { get; set; }
        public Exception InnerException { get; set; }
        public ExceptionData InnerExceptionData { get; set; }
        public bool IsException { get { return InnerException != null; } }

        public LogEntry(object message, Type messageType)
        {
            Message = message;
            MessageType = messageType;
        }
        public LogEntry(Exception exception)
        {
            InnerException = exception;
            InnerExceptionData = new ExceptionData(InnerException);
            MessageType = typeof(string);
            Message = string.Empty;
        }

        private DateTime _timeStamp;
        private string _machineName;
        private string _machineIp;
        private string _appDomainName;
        private string _processId;
        private string _processName;
        private string _managedThreadName;
        private string _win32ThreadId;
        /// <summary>
        /// 时间戳
        /// </summary>
        public DateTime TimeStamp
        {
            get
            {
                if (_timeStamp == DateTime.MinValue)
                {
                    _timeStamp = DateTime.Now;
                }
                return _timeStamp;
            }
            set
            {
                _timeStamp = value;
            }
        }
        /// <summary>
        /// 主机名称
        /// </summary>
        public string MachineName
        {
            get
            {
                if (string.IsNullOrEmpty(_machineName))
                {
                    try
                    {
                        _machineName = Environment.MachineName;
                    }
                    catch
                    {
                        _machineName = "未知";
                    }
                }
                return _machineName;
            }
            set
            {
                _machineName = value;
            }
        }
        /// <summary>
        /// 主机IP地址
        /// </summary>
        public string MachineIp
        {
            get
            {
                if (string.IsNullOrEmpty(_machineIp))
                {
                    try
                    {
                        _machineIp = GetLocalIp();
                    }
                    catch
                    {
                        _machineIp = "未知";
                    }
                }
                return _machineIp;
            }
            set
            {
                _machineIp = value;
            }
        }
        /// <summary>
        /// 用户程序名
        /// </summary>
        public string AppDomainName
        {
            get
            {
                if (string.IsNullOrEmpty(_appDomainName))
                {
                    try
                    {
                        _appDomainName = AppDomain.CurrentDomain.FriendlyName;
                    }
                    catch
                    {
                        _appDomainName = "未知";
                    }

                }
                return _appDomainName;
            }
            set
            {
                _appDomainName = value;
            }
        }
        /// <summary>
        /// 当前进程ID
        /// </summary>
        public string ProcessId
        {
            get
            {
                if (string.IsNullOrEmpty(_processId))
                {
                    try
                    {
                        GetCurrentProcessId().ToString(NumberFormatInfo.InvariantInfo);
                    }
                    catch
                    {
                        _processId = "未知";
                    }
                }
                return _processId;
            }
            set
            {
                _processId = value;
            }
        }
        /// <summary>
        /// 当前进程名
        /// </summary>
        public string ProcessName
        {
            get
            {
                if (string.IsNullOrEmpty(_processName))
                {
                    try
                    {
                        StringBuilder buffer = new StringBuilder(1024);
                        int length = GetModuleFileName(GetModuleHandle(null), buffer, buffer.Capacity);
                        _processName = buffer.ToString();
                    }
                    catch
                    {
                        _processName = "未知";
                    }
                }
                return _processName;
            }
            set
            {
                _processName = value;
            }
        }
        /// <summary>
        /// 当前运行线程名
        /// </summary>
        public string ManagedThreadName
        {
            get
            {
                if (string.IsNullOrEmpty(_managedThreadName))
                {
                    try
                    {
                        _managedThreadName = Thread.CurrentThread.Name;
                    }
                    catch
                    {
                        _managedThreadName = "未知";
                    }
                }
                return _managedThreadName;
            }
            set
            {
                _managedThreadName = value;
            }
        }
        /// <summary>
        /// 当前运行线程ID
        /// </summary>
        public string Win32ThreadId
        {
            get
            {
                if (string.IsNullOrEmpty(_win32ThreadId))
                {
                    try
                    {
                        _win32ThreadId = GetCurrentThreadId().ToString(NumberFormatInfo.InvariantInfo);
                    }
                    catch
                    {
                        _win32ThreadId = "未知";
                    }
                }
                return _win32ThreadId;
            }
            set
            {
                _win32ThreadId = value;
            }
        }
        /// <summary>
        /// 当前主机IP地址
        /// </summary>
        /// <returns></returns>
        private static string GetLocalIp()
        {
            string ret = string.Empty;
            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
            foreach (IPAddress ip in ips)
            {
                if (ip.IsIPv6LinkLocal)
                { continue; }
                else
                {
                    ret = ip.ToString();
                    break;
                }
            }
            return ret;
        }

        [DllImport("kernel32.dll")]
        public static extern int GetCurrentProcessId();

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [PreserveSig]
        public static extern int GetModuleFileName([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In] [MarshalAs(UnmanagedType.U4)] int nSize);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        public static extern IntPtr GetModuleHandle(string moduleName);

        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();
    }
}
